import Sprite from '../base/sprite'
import Bullet from './bullet'
import ShotGunBullet from './shotgunbullet'
import Protector from './protector'
import DataBus from '../databus'

const screenWidth = window.innerWidth
const screenHeight = window.innerHeight
const __ = {
  speed: Symbol('speed')
}

// 玩家相关常量设置
const PLAYER_IMG_SRC = 'images/hero.png'
const PLAYER_SCOT_SRC = 'images/scot.png'
const PLAYER_WIDTH = 80
const PLAYER_HEIGHT = 80

const databus = new DataBus()

export default class Player extends Sprite {
  constructor(speed, blood) {
    super(PLAYER_IMG_SRC, PLAYER_WIDTH, PLAYER_HEIGHT)

    // 玩家默认处于屏幕底部居中位置
    this.x = screenWidth / 2 - this.width / 2
    this.y = screenHeight - this.height - 30

    this.scotImg = PLAYER_SCOT_SRC;

    // 用于在手指移动的时候标识手指是否已经在飞机上了
    this.touched = false

    this.playerBlood = blood

    this.bullets = []

    this[__.speed] = speed

    // 初始化事件监听
    // 这个是原来跟着鼠标走的，现在换成由 contorller 给定位置，然后自动走
    // this.initEvent()
    this.init()
  }



  drawToCanvas(ctx) {

    if(this.isprotecting()) {
      const proterX = this.x - 30
      const proterY = this.y - 40
      this.proter.drawScot(ctx, proterX, proterY)
    }
    
    super.drawToCanvas(ctx)
  }

  isprotecting() {
    if(databus.frame <= this.toframe) {
      return true
    }
    return false
  }

  isShotGun() {
    if(databus.frame <= this.shotGunToframe) {
      return true
    }
    return false
  }

  protected(toframe) {
    // record protected to frame
    this.toframe = toframe
    const proterWidth = this.width + 60
    const proterHeight = this.height + 60
    this.proter = new Protector(proterWidth, proterHeight)
  }
  
  gotShotGun(toframe) {

    // record protected to frame
    this.shotGunToframe = toframe
  }

  decreaseBlood() {
    this.playerBlood -= 1;
  }

  getBlood() {
    return this.playerBlood;
  }

  /**
   * 当手指触摸屏幕的时候
   * 判断手指是否在飞机上
   * @param {Number} x: 手指的X轴坐标
   * @param {Number} y: 手指的Y轴坐标
   * @return {Boolean}: 用于标识手指是否在飞机上的布尔值
   */
  checkIsFingerOnAir(x, y) {
    const deviation = 30

    return !!(x >= this.x - deviation
              && y >= this.y - deviation
              && x <= this.x + this.width + deviation
              && y <= this.y + this.height + deviation)
  }

  /**
   * 根据手指的位置设置飞机的位置
   * 保证手指处于飞机中间
   * 同时限定飞机的活动范围限制在屏幕中
   */
  setAirPosAcrossFingerPosZ(x, y) {
    let disX = x - this.width / 2
    let disY = y - this.height / 2

    if (disX < 0) disX = 0

    else if (disX > screenWidth - this.width) disX = screenWidth - this.width

    if (disY <= 0) disY = 0

    else if (disY > screenHeight - this.height) disY = screenHeight - this.height

    this.x = disX
    this.y = disY
  }

  /**
   * 根据点击位置，设置目标位置
   * @param {*} x 
   * @param {*} y 
   */
  setAimPosByEventPos(x, y) {
    let disX = x - this.width / 2
    let disY = y - this.height / 2
    if (disX < 0) {
      disX = 0
    } else if (disX > screenWidth - this.width) {
      disX = screenWidth - this.width
    }
    if (disY <= 0) {
      disY = 0
    } else if (disY > screenHeight - this.height) {
      disY = screenHeight - this.height
    }
    this.aimX = disX
    this.aimY = disY
    let a = this.aimX - this.x
    let b = this.aimY - this.y
    let c = Math.sqrt(a * a + b * b)
    let sinB = b/c
    let cosB = a/c
    this.btmp = sinB * this[__.speed];
    this.atmp = cosB * this[__.speed];
  }

  /**
   * 玩家响应手指的触摸事件
   * 改变战机的位置
   */
  initEvent() {
    canvas.addEventListener('touchstart', ((e) => {
      e.preventDefault()

      const x = e.touches[0].clientX
      const y = e.touches[0].clientY

      //
      if (this.checkIsFingerOnAir(x, y)) {
        this.touched = true

        this.setAirPosAcrossFingerPosZ(x, y)
      }
    }))

    canvas.addEventListener('touchmove', ((e) => {
      e.preventDefault()

      const x = e.touches[0].clientX
      const y = e.touches[0].clientY

      if (this.touched) this.setAirPosAcrossFingerPosZ(x, y)
    }))

    canvas.addEventListener('touchend', ((e) => {
      e.preventDefault()

      this.touched = false
    }))
  }

  
  /**
   * 玩家响应手指的触摸事件, 读取触摸点坐标
   * 向坐标以 speed 为速度进行位移
   */
  init() {

    this.moving = false
    canvas.addEventListener('touchstart', ((e) => {
      e.preventDefault()
      this.ctmp = 0
      this.moving = true
      const x = e.touches[0].clientX
      const y = e.touches[0].clientY

      this.setAimPosByEventPos(x, y)
    }))
  }

  // 每一帧更新位置并判断是否达到目标位置 ，因为 x 和 y 方向的增量是按正弦、余弦计算出来的投影值，
  // 所以任意一个方向到达了， 另外一个方向也必定到达，因此只要判断一个方向是否到达就OK了
  update() {
    if(this.moving) {
      this.x += this.atmp
      this.y += this.btmp
      if(this.atmp > 0) {
        if(this.x > this.aimX) {
          this.x = this.aimX
          this.moving = false
        }
      } else if(this.atmp < 0) {
        if(this.x < this.aimX) {
          this.x = this.aimX
          this.moving = false
        }
      } else {
        this.moving = false
      }

      

    }

  }

  /**
   * 玩家射击操作
   * 射击时机由外部决定
   */
  shoot() {
    
    if(this.isShotGun()) {
      this.shootByShotGun()
    } else {
      this.shootByCommonGun()
    }
    
  }

  shootByCommonGun() {
    const bullet = databus.pool.getItemByClass('bullet', Bullet)
    bullet.init(
      this.x + this.width / 2 - bullet.width / 2,
      this.y - 10,
      10
    )
    databus.bullets.push(bullet)
  }

  shootByShotGun() {
    const firstTheata = -10;
    for (let i = 0, il = 3; i < il; i++) {
      const theata = firstTheata +  i * 10
      const bullet = databus.pool.getItemByClass('shotgunbullet', ShotGunBullet)
      bullet.init(
        this.x + this.width / 2 - bullet.width / 2,
        this.y - 10,
        10,
        theata
      )
      databus.bullets.push(bullet)
    }

  }
}
